using System.Text;
namespace array_demo.Model
{
    /// <summary>
    /// 循环数组
    /// </summary>
    /// <typeparam name="E"></typeparam>
    public class Array2<E>
    {
        private E[] data;
        private int N;

        /// <summary>
        /// 标记数组头部的位置
        /// </summary>
        /// <value></value>
        private int first { get; set; }

        /// <summary>
        /// 标记数组尾部的位置
        /// </summary>
        /// <value></value>
        private int last { get; set; }

        public Array2(int capacity)
        {
            data = new E[capacity];
            first = 0;
            last = 0;
            N = 0;
        }

        public Array2() : this(10)
        {

        }

        /// <summary>
        /// 获取数组的个数
        /// </summary>
        public int Count
        {
            get
            {
                return N;
            }
        }

        public bool IsEmpty
        {
            get { return N == 0; }
        }


        public E GetFirst()
        {
              if (first < 0 || first > N)
            {
                throw new AggregateException("数组索引越界");
            }
            return data[first];
        }


        /// <summary>
        /// 尾部新增元素
        /// </summary>
        /// <param name="e"></param>
        public void AddLast(E e)
        {
            if (N == data.Length)
            {
                ResetCapacity(2 * data.Length);
            }

            data[last] = e;
            last = (last + 1) % data.Length;
            N++;
        }

        /// <summary>
        /// 删除头部元素
        /// </summary>
        /// <returns></returns>
        public E DeleteFirst()
        {
            if (data.Length == 0)
            {
                throw new InvalidOperationException("数组为空");
            }

            E ret = data[first];
            data[first] = default(E);
            first = (first + 1) % data.Length;
            N--;

            if (N == data.Length / 4)
            {
                ResetCapacity(data.Length / 2);
            }
            return ret;
        }


        /// <summary>
        /// 设置容量  
        /// </summary>
        /// <param name="capacity"></param>
        private void ResetCapacity(int capacity)
        {
            E[] newData = new E[capacity];
            // 拷贝元素到新数组中
            for (int i = 0; i < N; i++)
            {
                newData[i] = data[(last + i) % data.Length];
            }
        }


        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("[");
            for (int i = 0; i < N; i++)
            {
                stringBuilder.Append(data[(first + 1) % data.Length]);
                if ((first + 1) % data.Length != last)
                {
                    stringBuilder.Append(",");
                }
            }
            stringBuilder.Append("]");
            return stringBuilder.ToString();
        }
    }
}